home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / Macintosh Sample Code / SC.012.Signals / register variables next >
Encoding:
Text File  |  1988-10-31  |  2.6 KB  |  71 lines  |  [TEXT/MPS ]

  1. Register Variables (for both Pascal and C programmers)
  2.  
  3. If you take a look at TestCignal.c, the C version of the signal-testing MPW tool,
  4. you will note the following code in main():
  5.  
  6.     volatile long        registerLong = 0;
  7.     
  8.     InitUFailure();
  9.  
  10.     if (code = CatchSignal()) {
  11.         fprintf(stdout, "Signal caught in main; code = %d, (registerLong = %d)\n",
  12.             code, registerLong);
  13.         return 0;
  14.     }
  15.     
  16.     registerLong = 0xffff;
  17.     
  18.     Signal(Value());
  19.  
  20. The storage specifier volatile is used in the declaration of registerLong because
  21. of a potential problem with the value of register variables at the point of the
  22. CatchSignal(). This problem can occur when using longjmp() as well.
  23.  
  24. What happens is that the compiler (being a clever little fellow) decides that a
  25. local scalar variable can be conveniently kept in a register. When the exception is
  26. raised, all non-scratch registers are restored to what they were before the
  27. CatchSignal() call. If registerLong is kept in D3, for instance, then it will have
  28. the value 0 instead of 0xffff while processing the exception.
  29.  
  30. This can be a serious problem if the register variable holds something like a
  31. handle or pointer, since you are likely to want to dispose of the block that it
  32. references if an exception occurs.
  33.  
  34. In C this potential difficulty can be avoided by declaring a variable volatile. The
  35. compiler will keep a local variable on the stack and not leave it in a register. So,
  36. the printf() displays the correct value of 65535. If you removed the volatile
  37. storage specifier, 0 would be value of registerLong when printf() was called. If there
  38. is any doubt about a variable in your C program, be volatile.
  39.  
  40.  
  41. In the Pascal TestSignal tool in Main:
  42.  
  43.         registerLong:    LONGINT;
  44.  
  45.     BEGIN
  46. {InitSignals has already been done}
  47.         registerLong := 0;
  48.         
  49.         {catch Signals not otherwise caught by the program}
  50.         code := CatchSignal;
  51.         IF code <> 0 THEN BEGIN
  52.             NumToString(code, aString);
  53.             aString := Concat('Signal caught from main, code = ',aString,
  54.                 ', registerLong = ');
  55.             DoCatchOutMain(aString, registerLong);
  56.         END;
  57.         
  58.         registerLong := $FFFF;
  59.         
  60.         Signal(Value);
  61.  
  62.  
  63. The Pascal tool displays zero for the value of registerLong since the compiler keeps
  64. it in a D register. This means that you must be careful in your use of local variables
  65. when CatchSignal is involved. This is never a problem when using CatchFailures since
  66. the handler is a separate procedure and any locals of an enclosing procedure would be
  67. pulled off the stack by the handler.
  68.  
  69. Apple is investigating ways to get the same kind of control in Pascal that the
  70. volatile storage specifier gives you in C. A future version of MPW Pascal will almost
  71. certainly have this capability.